<?php
/**
 * @author barry
 * dbProxy : null 表示遵从db config的主从配置
 * dbProxy : master/slave 表示强制读写主库
 */
class Database{
	
	private $_objDb = null;
	
	public function __construct($arrArgs) {
		$strDbName = !empty($arrArgs[0]) ? $arrArgs[0] : '';
		$strProxy = !empty($arrArgs[1]) ? $arrArgs[1] : null;
		$this->_objDb = core::db()->getConnect($strDbName, $strProxy);
	}
	
	/**
	 * 添加数据
	 * @param string $strTable
	 * @param array $arrData
	 * @return int
	 */
	public function add($strTable, Array $arrData) {
		if (!empty($arrData)) {
			$arrFields = array();
			$arrValues = array();
			foreach ($arrData as $key => $value) {
				$arrFields[] = '`' . $key . '`';
				if (!get_magic_quotes_gpc()) {
					$arrValues[] = addslashes($value);
				}
			}
			$strFields = implode(',', $arrFields);
			$strValues = implode("','", $arrValues);
			$strSql = "INSERT INTO tbl_" . $strTable . " (" . $strFields . ") VALUES ('" . $strValues . "')";
			$boolRes = $this->_objDb->query($strSql);
			if ($boolRes) {
				$insertId = $this->_objDb->insertId();
			} else {
				$insertId = 0;
			}
		} else {
			$insertId = 0;
		}
		return $insertId;
	}
	
	
	/**
	 * 更新数据库操作
	 * @param unknown_type $strTables
	 * @param unknown_type $arrWhere
	 * @param unknown_type $arrData
	 */
	public function update($strTable, Array $arrData, Array $arrWhere, Array $arrOption = array()) {
		$strWhere = $this->dealWhere($arrWhere);;
		$strData = '';
		$strWhere .= !empty($arrOption['like']) ? " AND like" . $arrOption['like'] : '';
		$strWhere .= !empty($arrOption['group']) ? " GROUP BY " . $arrOption['group'] : '';
		$strWhere .= !empty($arrOption['order']) ? " ORDER BY " . $arrOption['order'] : '';
		$strWhere .= !empty($arrOption['limit']) ? " limit " . $arrOption['limit'] : '';
		if (!empty($arrData)) {
			foreach ($arrData as $key => $value) {
				$strData .= "`" . $key . "`='" . $value . "',";
			}
			$strData = substr($strData, 0, -1);
		}
		$strSql = "UPDATE tbl_" . $strTable . " SET " . $strData . " WHERE " . $strWhere;
		$boolRes = $this->_objDb->query($strSql);
		return $boolRes;
	}
	
	/**
	 * 删除数据
	 * @param string $strTable
	 * @param array $arrWhere
	 * @return boolean
	 */
	public function delete($strTable, Array $arrWhere) {
		if (!empty($arrWhere)) {
			$strWhere = $this->dealWhere($arrWhere);
			$strSql = "DELETE FROM tbl_" . $strTable . " WHERE " . $strWhere;
			$boolRes = $this->_objDb->query($strSql);
			return $boolRes;
		}
		return false;
	}
	
	/**
	 * 查询数据
	 * @param string $strTable
	 * @param array $arrWhere
	 * @param array $arrFileld
	 * @param array $arrOption
	 * @return array
	 * 
	 * $arrWhere = array (
		 array ('and', 'name=1', 'age>2', 'key<3'),
		 array ('(or)', 'age=1', 'age=3'),
		 array ('or', 'age=1']),
		 array ('in', 'id', array('1','2','3')),
		 array ('!in', 'id', array(1,2,3)),
		 array ('like', 'name', '%wufaliang%']),
		 array ('!like', 'name', '%wufaliang%'),
	   );
	   $arrOption = array (
		 'order' => 'id desc, name desc'
		 'group' => 'name',
		 'limit' => '1,3',
	   );
	   select * from table where name='wfl_liu@163.com' and password='password' and hello in (1,3,2) and age != 14 or (keys =)'
	 */
	public function select($strTable, Array $arrWhere, Array $arrOption = array(), Array $arrFileld = array()) {
		$strWhere = $this->dealWhere($arrWhere);
		$strFileld = '';
		$strWhere .= !empty($arrOption['like']) ? " AND like" . $arrOption['like'] : '';
		$strWhere .= !empty($arrOption['group']) ? " GROUP BY " . $arrOption['group'] : '';
		$strWhere .= !empty($arrOption['order']) ? " ORDER BY " . $arrOption['order'] : '';
		$strWhere .= !empty($arrOption['limit']) ? " limit " . $arrOption['limit'] : '';
		if (!empty($arrFileld)) {
			foreach ($arrFileld as $fileld) {
				$strFileld .= "`" . $fileld . "`,";
			}
			$strFileld = substr($strFileld, 0, -1);
		} else {
			$strFileld = '*';
		}
		$strSql = "SELECT " . $strFileld . " FROM tbl_" . $strTable . " WHERE " . $strWhere;
		$objData = $this->_objDb->query($strSql);
		while ($arrDataTemp = $this->_objDb->fetchArray($objData)) {
			$arrData[] = $arrDataTemp;
		}
		return $arrData;
	}
	
	/**
	 * 获取总数
	 * @param string $strTable
	 * @param array $arrWhere
	 * @param array $arrOption
	 * @return int
	 */
	public function total($strTable, Array $arrWhere, Array $arrOption = array()) {
		$strWhere = $this->dealWhere($arrWhere);
		$strFileld = '';
		$strWhere .= !empty($arrOption['like']) ? " AND like" . $arrOption['like'] : '';
		$strWhere .= !empty($arrOption['group']) ? " GROUP BY " . $arrOption['group'] : '';
		$strWhere .= !empty($arrOption['order']) ? " ORDER BY " . $arrOption['order'] : '';
		$strWhere .= !empty($arrOption['limit']) ? " limit " . $arrOption['limit'] : '';
		$strSql = "SELECT count(*) AS total FROM tbl_" . $strTable . " WHERE " . $strWhere;
		$objData = $this->_objDb->query($strSql);
		$arrdataTemp = $this->_objDb->fetchArray($objData);
		return $arrdataTemp['total'];
	}
	
	/**
	 * 事务开启
	 */
	public function begin() {
		return $this->_objDb->startTransaction();
	}
	
	/**
	 * 事务回滚
	 */
	public function rollback() {
		return $this->_objDb->rollback();
	}
	
	/**
	 * 事务提交
	 */
	public function commit() {
		return $this->_objDb->commit();
	}
	
	/**
	 * where条件处理
	 * @param array $arrWhere
	 * @return string
	 */
	private function dealWhere($arrWhere) {
		$strWhere = '1=1';
		if (!empty($arrWhere)) {
			foreach ($arrWhere as $key => $value) {
				switch ($value[0]) {
					case "and" :
						$strAnd = '';
						foreach ($value as $k => $v) {
							if ($k == 0) {
								continue;
							} else {
								if (strpos($v, '=') !== false) {
									$temp = explode('=', $v);
									$strAnd .= "`" . trim($temp['0']) . "`='" . addslashes(trim($temp[1])) . "' AND ";
								}
								if (strpos($v, '>') !== false) {
									$temp = explode('>', $v);
									$strAnd .= "`" . trim($temp['0']) . "`>'" . addslashes(trim($temp[1])) . "' AND ";
								}
								if (strpos($v, '<') !== false) {
									$temp = explode('<', $v);
									$strAnd .= "`" . trim($temp['0']) . "`<'" . addslashes(trim($temp[1])) . "' AND ";
								}
								if (strpos($v, '<>') !== false) {
									$temp = explode('<>', $v);
									$strAnd .= "`" . trim($temp['0']) . "`<>'" . addslashes(trim($temp[1])) . "' AND ";
								}
								if (strpos($v, '!=') !== false) {
									$temp = explode('!=', $v);
									$strAnd .= "`" . trim($temp['0']) . "`!='" . addslashes(trim($temp[1])) . "' AND ";
								}
							}
						}
						$strAnd = " AND " . substr($strAnd, 0, -5);
						$strWhere .= $strAnd;
						break;
					case "(or)" :
						$strAOr = '';
						foreach ($value as $k => $v) {
							if ($k == 0) {
								continue;
							} else {
								if (strpos($v, '=') !== false) {
									$temp = explode('=', $v);
									$strAOr .= "`" . trim($temp['0']) . "`='" . addslashes(trim($temp[1])) . "' OR ";
								}
								if (strpos($v, '>') !== false) {
									$temp = explode('>', $v);
									$strAOr .= "`" . trim($temp['0']) . "`>'" . addslashes(trim($temp[1])) . "' OR ";
								}
								if (strpos($v, '<') !== false) {
									$temp = explode('<', $v);
									$strAOr .= "`" . trim($temp['0']) . "`<'" . addslashes(trim($temp[1])) . "' OR ";
								}
								if (strpos($v, '<>') !== false) {
									$temp = explode('<>', $v);
									$strAOr .= "`" . trim($temp['0']) . "`<>'" . addslashes(trim($temp[1])) . "' OR ";
								}
								if (strpos($v, '!=') !== false) {
									$temp = explode('!=', $v);
									$strAOr .= "`" . trim($temp['0']) . "`!='" . addslashes(trim($temp[1])) . "' OR ";
								}
							}
						}
						$strAOr = " AND (" . substr($strAOr, 0, -4) . ")";
						$strWhere .= $strAOr;
						break;
					case "or" :
						$strOr = '';
						if (strpos($value[1], '=') !== false) {
							$temp = explode('=', $value[1]);
							$strOr .= "`" . trim($temp['0']) . "`='" . addslashes(trim($temp[1])) . "'";
						}
						if (strpos($value[1], '>') !== false) {
							$temp = explode('>', $value[1]);
							$strOr .= "`" . trim($temp['0']) . "`>'" . addslashes(trim($temp[1])) . "'";
						}
						if (strpos($value[1], '<') !== false) {
							$temp = explode('<', $value[1]);
							$strOr .= "`" . trim($temp['0']) . "`<'" . addslashes(trim($temp[1])) . "'";
						}
						if (strpos($value[1], '<>') !== false) {
							$temp = explode('<>', $value[1]);
							$strOr .= "`" . trim($temp['0']) . "`<>'" . addslashes(trim($temp[1])) . "'";
						}
						if (strpos($value[1], '!=') !== false) {
							$temp = explode('!=', $value[1]);
							$strOr .= "`" . trim($temp['0']) . "`!='" . addslashes(trim($temp[1])) . "'";
						}
						$strOr = " OR " . $strOr;
						$strWhere .= $strOr;
						break;
					case "in" :
						$strIn = " AND `" . trim($value[1]) . "` IN (" . implode(',', $value[2]) . ")";
						$strWhere .= $strIn;
						break;
					case "!in" :
						$strNotIn = " AND `" . trim($value[1]) . "` NOT IN (" . implode(',', $value[2]) . ")";
						$strWhere .= $strNotIn;
						break;
					case "like" :
						$strLike = " AND `" . trim($value[1]) . "` LIKE '" . $value[2] . "'";
						$strWhere .= $strLike;
						break;
					case "!like" :
						$strNoLike = " AND `" . trim($value[1]) . "` NOT LIKE '" . $value[2] . "'";
						$strWhere .= $strNoLike;
						break;
				}
			}
		}
		return $strWhere;
	}
}